package com.xue.apiautoframework.utils;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.xue.apiautoframework.constant.*;
import org.apache.poi.ss.usermodel.*;
import java.io.*;
import java.util.*;

/**
 * @Author xue
 * @Date 2021/6/29 22:45
 */
public class ExcelUtils {

    /**
     * 读取excel中第一个sheet,API， 通过read方法一次性把所有的接口数据都读取放到list集合里
     */
    public static List<API> apiList = readExcel(0, API.class, Constant.CASES_FILE_PATH);

    /**
     * 读取excel中第二个sheet,Case， 通过read方法一次性把所有的用例数据都读取放到list集合里
     */
    public static List<Cases> casesList = readExcel(1, Cases.class,Constant.CASES_FILE_PATH);

    /**
     * excel回写数据集合。
     */
    public static List<WriteBackData> wbdList = new ArrayList<>();

    /**
     * 读Excel中的数据
     * @param startSheetIndex 操作的sheet的索引值
     * @param clazz           字节码类型
     * @param filePath        文件路径
     * @param <E>             返回的类型
     * @return                返回一个list集合
     */
    public static <E> List<E> readExcel(int startSheetIndex, Class<E> clazz, String filePath){
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(filePath);
            ImportParams params = new ImportParams();
            params.setStartSheetIndex(startSheetIndex);
            params.setNeedVerify(true);
            return ExcelImportUtil.importExcel(fis, clazz, params);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close(fis);
        }
        return null;

    }

    /**
     * 添加回写对象到集合中
     * @param rowNum   回写的行号
     * @param cellNum  回写的列号
     * @param content  回写的内容
     */
    public static void addWriteBackDataToList(int rowNum, int cellNum, String content){
        WriteBackData writeBackData = new WriteBackData(rowNum, cellNum, content);
        wbdList.add(writeBackData);
    }

    /**
     * 批量回写数据到Excel中
     * 确定需要回写的行、列、回写内容。列可以自定义一个固定的，放在常量类里
     */
    public static void batchWrite(){
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(Constant.CASES_FILE_PATH);
            //创建excel对象
            Workbook workbook = WorkbookFactory.create(fis);
            //读取需要打开的用例页签，以索引值读取
            Sheet sheet = workbook.getSheetAt(1);

            //遍历wbdList集合
            for (WriteBackData writeBackData : wbdList) {
                //获取行号及行对象
                int rowNum = writeBackData.getRow();
                Row row = sheet.getRow(rowNum);
                //获取列号及单元格对象
                int cellNum = writeBackData.getCellNum();
                Cell cell = row.getCell(cellNum, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                //获取回写内容，设置到表格中
                cell.setCellType(CellType.STRING);
                String content = writeBackData.getContent();
                cell.setCellValue(content);
            }
            //内容回写到文件中
            fos = new FileOutputStream(Constant.CASES_FILE_PATH);
            workbook.write(fos);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            close(fos);
            close(fis);
        }
    }

    /**
     * 从已经读取好的所有List<API>和所有List<Case>两个集合中获取符合条件的数据
     * @param apiId  接口编号，用于匹配接口信息和用例中的接口编口
     */
    public static Object[][] getApiAndCasesByApiId(String apiId){

        //需要的API对象，接口信息一个接口编号只有一个
        API wantApi = null;

        //需要的Case集合，用例一个接口编号有多个用例，所有定义一个list集合
        List<Cases> wantCaseList = new ArrayList<>();

        // 匹配api对象那个
        for (API api : apiList) {
            if (apiId.equals(api.getApiNumber())){
                wantApi = api;
                break;
            }
        }

        //匹配Cases对象
        for (Cases cases : casesList) {
            if (apiId.equals(cases.getApiNumber())){
                wantCaseList.add(cases);
            }
        }

        // wantCaseList.size()是cases的个数,表示有多个case, 2 表示二维数组里元素的个数
        Object[][] data = new Object[wantCaseList.size()][2];
        for (int i = 0; i < wantCaseList.size(); i++) {
            data[i][0] = wantApi;
            data[i][1] = wantCaseList.get(i);
        }
        return data;
    }

    /**
     * 关闭流操作
     * @param stream 流对象
     */
    private static void close(Closeable stream) {
        if (stream != null){
            try {
                stream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        String filePath = "src/main/resources/config/case.xlsx";
        Objects.requireNonNull(readExcel(0, API.class, filePath)).forEach(System.out::println);
    }
}
